#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define MUTEX_AB 0
#define MUTEX_CD 1

void display(char *str) 
{
  char *tmp;
  for (tmp=str;*tmp;tmp++) {
    write(1, tmp, 1);
    usleep(100);
  }
}

void * second_thread(void * arg)
{
  pthread_mutex_t * * mutex = (pthread_mutex_t * *)arg;
  int i;
  for (i=0;i<10;i++) {
    pthread_mutex_lock(mutex[MUTEX_AB]);
    display("ab");
    pthread_mutex_unlock(mutex[MUTEX_CD]);
  }
  return 0;
}

pthread_t create_thread(void * (*fun)(void *), void * args) 
{
  pthread_t id;
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_create(&id, &attr, fun, args);
  return id;
}

pthread_mutex_t * create_mutex()
{
  pthread_mutex_t * mutex = malloc(sizeof(pthread_mutex_t));
  pthread_mutexattr_t attr;
  pthread_mutexattr_init(&attr);
  pthread_mutex_init(mutex, &attr);
  return mutex;
}

int main() 
{
  int i;
  pthread_mutex_t * mutex[2];
  mutex[0] = create_mutex();
  mutex[1] = create_mutex();
  pthread_t id = create_thread(&second_thread, mutex);
  pthread_mutex_lock(mutex[MUTEX_CD]);

  for (i=0;i<10;i++) {
    pthread_mutex_lock(mutex[MUTEX_CD]);
    display("cd\n");
    pthread_mutex_unlock(mutex[MUTEX_AB]);
  }
  
  pthread_join(id, NULL);
  pthread_mutex_destroy(mutex[MUTEX_AB]);
  pthread_mutex_destroy(mutex[MUTEX_CD]);
  return 0;
}

